package linuxbox.common;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;

import linuxbox.BoxStatic;
import linuxbox.exception.*;

public class ActionServlet extends HttpServlet {
    protected static Logger logger =
        Logger.getLogger(ActionServlet.class.getName());
    Class keepStatics = BoxStatic.class;

    public void init(ServletConfig config) throws ServletException {
        try {
            super.init(config);
            //Call BasicConfigurator.configure() as early as possible
            BasicConfigurator.configure();

            String configFile =
                config.getInitParameter(BoxStatic.MAIN_CONFIG_FILE);
            if (configFile == null)
                throw new ServletException(
                                           "Missing main channel file "
                                           + "parameter in config file.");

            String homePath =
                config.getServletContext().getRealPath(File.separator);
            if (homePath.charAt(homePath.length() - 1) != File.separatorChar) {
                homePath = homePath + File.separator;
            }
            BoxStatic.logger.debug("home dir is " + homePath);
            BoxStatic.logger.debug("config file is " + configFile);

            BoxInit bi = BoxInit.getInstance(configFile, homePath);
            //bi.initSystem();
            //BoxStatic.moduleControl.initServlet(this);
            bi.zInitSystem();
            BoxStatic.mainConfig.setServlet(this);

            logger.debug(
                         "getServletContextName:"
                         + config.getServletContext().getServletContextName());
            // read BoxStatic info from BoxConfig.xml
            BoxStatic.zinit();
        } catch (Exception e) {
            logger.debug(e);
            e.printStackTrace();
            throw new UnavailableException("Init Error: " + e.getMessage());
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        process(request, response);
    }

    public void doPost(
                       HttpServletRequest request,
                       HttpServletResponse response)
        throws IOException, ServletException {
        process(request, response);
    }

    protected void process(
                           HttpServletRequest request,
                           HttpServletResponse response)
        throws IOException, ServletException {
        //ServletContext aContext = getServletContext();
        //BoxStatic.logger.debug("ServletContext is " + aContext);

        // Identify the path component we will use to select a mapping
        String path = processPath(request);
        logger.debug("Path is " + path);

        if (path == null) {
            logger.error(
                         "No path available for request URI " + request.getRequestURI());
            response.sendError(
                               HttpServletResponse.SC_BAD_REQUEST,
                               "processPath");
            return;
        }

        logger.debug("Processing a " + request.getMethod() + " for " + path);
        callAction(path, request, response);

        //callAction("test", request, response);
    }

    protected String processPath(HttpServletRequest req) {
        String path = req.getPathInfo();
        if (path != null)
            path = path.substring(1);

        return path;
    }

    public void callAction(
                           String aAction,
                           HttpServletRequest req,
                           HttpServletResponse res) {
        try {
            //Action action = BoxStatic.moduleControl.getAction(aAction);
            Action action = BoxStatic.mainConfig.getAction(aAction);
            logger.debug("action is " + action);

            if (action != null)
                action.doAction(req, res);
            else {
                logger.error("Calling action: " + aAction);
                // throw new LinuxboxException("Error calling action:" +
                // aAction);
            }

            /*
             * res.setContentType("text/html");
             *
             * //ServletOutputStream out = res.getOutputStream(); PrintWriter
             * out = new PrintWriter(res.getOutputStream());
             *
             * out.println(" <html><head><title> Hello World! </title>
             * </head> "); out.println(" <body><h1> Hello World! </h1> ");
             * out.println(" </body></html> "); out.flush();
             *
             */
        } catch (Exception exc) {
            logger.error("Calling action:" + aAction + " error!");
            sendError(exc, req, res);
        }
    }

    public void sendError(
                          Exception aException,
                          HttpServletRequest aReq,
                          HttpServletResponse aRes) {
        try {
            logger.error(aException);

            String path =
                aReq.getContextPath() + "/" + BoxStatic.defaultLang + "/jsp/";

            if (aException == LinuxboxException.NO_USER) {
                aRes.sendRedirect(path + BoxStatic.noUserJSP);
            } else if (aException == LinuxboxException.TIMEOUT) {
                aRes.sendRedirect(path + BoxStatic.timeoutJSP);
            } else if ( aRes instanceof AccessRightException) {
              aRes.sendRedirect(path + BoxStatic.accessRightErrorJSP);
            }
            else  {
                HttpSession httpSession = aReq.getSession();
                if (httpSession != null) {
                    httpSession.setAttribute(BoxStatic.EXCEPTION, aException);
                    aRes.sendRedirect(path + BoxStatic.errorJSP);
                }
            }
        } catch (Exception e) {
            logger.error(e);
        }
    }
}
